-module(ebbs_user).

-include_lib("stdlib/include/qlc.hrl").
-include_lib("user.hrl").

-define(TABLE, ebbs_user).

-compile(export_all).

init() ->
    try mnesia:table_info(?TABLE, disc_copies) of
	_ -> ok
    catch
	exit: {aborted, {no_exists, ?TABLE, disc_copies}} ->
	    mnesia:create_table(?TABLE,
				[{attributes, record_info(fields, user)},
				 {disc_copies, [node()]},
				 {index, [cert_sha1]},
				 {record_name, user},
				 {type, set}]);
	  _:E -> exit(E)
    end.

find(Id) ->
    F = fun () -> mnesia:read({?TABLE, Id}) end,
    {atomic, User} = mnesia:transaction(F),
    User.

find_by_pubkey(Key) ->
    F = fun () ->
		qlc:e(qlc:q([User || User <- mnesia:table(?TABLE),
				     User#user.cert_sha1 =:= Key]))
	end,
    {atomic, Users} = mnesia:transaction(F),
    Users.

add(User) when is_record(User, user) ->
    F = fun () ->
		case mnesia:read({?TABLE, User#user.id}) of
		    [] -> void;
		    _ -> mnesia:abort(already_exist)
		end,
		mnesia:write(?TABLE, User, write)
	end,
    {_, Result} = mnesia:transaction(F),
    Result.

delete(Id) ->
    F = fun () -> mnesia:delete({?TABLE, Id}) end,
    {_, Result} = mnesia:transaction(F),
    Result.

delete_by_pubkey(Key) ->
    F = fun () ->
		Users = find_by_pubkey(Key),
		lists:map(fun (User) ->
				  mnesia:delete({?TABLE, User#user.id})
			  end,
			  Users)
	end,
    {_, Result} = mnesia:transaction(F),
    Result.

%% old user must exist, new user mustn't exist.
%% A user can change his id.
update(Id, User) when is_record(User, user) ->
    F = fun () ->
		case mnesia:wread({?TABLE, Id}) of
		    [] -> mnesia:abort(not_found);
		    _ -> void
		end,
		if
		    Id =/= User#user.id ->
			case mnesia:read({?TABLE, User#user.id}) of
			    [] -> mnesia:delete({?TABLE, Id});
			    _ -> mnesia:abort(already_exist)
			end;
		    true -> void
		end,
		mnesia:write(?TABLE, User, write)
	end,
    {_, Result} = mnesia:transaction(F),
    Result.

list() ->
    F = fun () ->
		qlc:e(qlc:q([User || User <- mnesia:table(?TABLE)]))
	end,
    {atomic, Users} = mnesia:transaction(F),
    Users.

clear() ->
    {_, Result} = mnesia:clear_table(?TABLE),
    Result.

